home *** CD-ROM | disk | FTP | other *** search
/ MacWorld 2003 August / MW 8 2003 CD1.iso / Inside Macworld / Product News / gimp-1.2.4.sit / gimp-1.2.4 / libgimp / gimp.c < prev    next >
Encoding:
C/C++ Source or Header  |  2003-02-17  |  27.8 KB  |  1,209 lines

  1. /* LIBGIMP - The GIMP Library
  2.  * Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
  3.  *
  4.  * gimp.c
  5.  *
  6.  * This library is free software; you can redistribute it and/or
  7.  * modify it under the terms of the GNU Lesser General Public
  8.  * License as published by the Free Software Foundation; either
  9.  * version 2 of the License, or (at your option) any later version.
  10.  *
  11.  * This library is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14.  * Library General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU Lesser General Public
  17.  * License along with this library; if not, write to the
  18.  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  19.  * Boston, MA 02111-1307, USA.
  20.  */
  21.  
  22. #include "config.h"
  23.  
  24. #include <locale.h>
  25. #include <errno.h>
  26. #include <stdarg.h>
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29. #include <string.h>
  30. #include <sys/types.h>
  31.  
  32. #ifdef HAVE_SYS_TIME_H
  33. #include <sys/time.h>
  34. #endif
  35.  
  36. #ifdef HAVE_SYS_PARAM_H
  37. #include <sys/param.h>
  38. #endif
  39.  
  40. #ifdef HAVE_SYS_WAIT_H
  41. #include <sys/wait.h>
  42. #endif
  43.  
  44. #ifdef HAVE_UNISTD_H
  45. #include <unistd.h>
  46. #endif
  47.  
  48. #ifndef WAIT_ANY
  49. #define WAIT_ANY -1
  50. #endif
  51.  
  52. #include <glib.h>
  53.  
  54. #ifndef G_OS_WIN32
  55. #include "gimpsignal.h"
  56. #else
  57. #include <signal.h>
  58. #endif
  59.  
  60. #include "gimpenv.h"
  61.  
  62. #ifdef HAVE_IPC_H
  63. #include <sys/ipc.h>
  64. #endif
  65.  
  66. #ifdef HAVE_SHM_H
  67. #include <sys/shm.h>
  68. #endif
  69.  
  70. #ifdef HAVE_SYS_SELECT_H
  71. #include <sys/select.h>
  72. #endif
  73.  
  74. #if defined(G_OS_WIN32) || defined(G_WITH_CYGWIN)
  75. #  define STRICT
  76. #  undef DATADIR        /* typedefed in objidl.h... the value
  77.                    from Makefile not used here anyway */
  78. #  include <windows.h>
  79. #  undef RGB
  80. #endif
  81. #ifdef __EMX__
  82. #  include <fcntl.h>
  83. #endif
  84.  
  85. #define LIBGIMP_COMPILATION
  86.  
  87. #include "gimp.h"
  88. #include "gimpprotocol.h"
  89. #include "gimpwire.h"
  90.  
  91.  
  92. #define WRITE_BUFFER_SIZE  1024
  93.  
  94. void gimp_extension_process (guint        timeout);
  95. void gimp_extension_ack     (void);
  96. void gimp_read_expect_msg   (WireMessage *msg,
  97.                  gint         type);
  98.  
  99.  
  100. #ifndef G_OS_WIN32
  101. static void       gimp_plugin_sigfatal_handler (gint            sig_num);
  102. #endif
  103. static gboolean   gimp_plugin_io_error_handler (GIOChannel     *channel,
  104.                         GIOCondition    cond,
  105.                         gpointer        data);
  106.  
  107. static gboolean   gimp_write                   (GIOChannel     *channel,
  108.                         guint8         *buf,
  109.                         gulong          count);
  110. static gboolean   gimp_flush                   (GIOChannel     *channel);
  111. static void       gimp_loop                    (void);
  112. static void       gimp_config                  (GPConfig       *config);
  113. static void       gimp_proc_run                (GPProcRun      *proc_run);
  114. static void       gimp_temp_proc_run           (GPProcRun      *proc_run);
  115. static void       gimp_message_func            (const gchar    *log_domain,
  116.                         GLogLevelFlags  log_level,
  117.                         const gchar    *message,
  118.                         gpointer        data);
  119. static void       gimp_process_message         (WireMessage    *msg);
  120. static void       gimp_close                   (void);
  121. #ifdef HACK_FOR_BUG_66859
  122. static void      gimp_have_init_proc          (void);
  123. #endif
  124.  
  125. GIOChannel *_readchannel  = NULL;
  126. GIOChannel *_writechannel = NULL;
  127.  
  128. gint    _shm_ID   = -1;
  129. guchar *_shm_addr = NULL;
  130.  
  131. guint gimp_major_version = GIMP_MAJOR_VERSION;
  132. guint gimp_minor_version = GIMP_MINOR_VERSION;
  133. guint gimp_micro_version = GIMP_MICRO_VERSION;
  134.  
  135. #if defined(G_OS_WIN32) || defined(G_WITH_CYGWIN)
  136. static HANDLE shm_handle;
  137. #endif
  138.  
  139. static gdouble  _gamma_val;
  140. static gboolean _install_cmap;
  141. static gboolean _use_xshm;
  142. static guchar   _color_cube[4];
  143. static gint     _min_colors;
  144. static gint     _gdisp_ID = -1;
  145.  
  146. static gchar   *progname = NULL;
  147. static guint8   write_buffer[WRITE_BUFFER_SIZE];
  148. static guint    write_buffer_index = 0;
  149.  
  150. static GimpStackTraceMode stack_trace_mode = GIMP_STACK_TRACE_NEVER;
  151.  
  152. static GHashTable *temp_proc_ht = NULL;
  153.  
  154. #ifdef G_OS_WIN32
  155. static GimpPlugInInfo *PLUG_IN_INFO_PTR;
  156. #define PLUG_IN_INFO (*PLUG_IN_INFO_PTR)
  157. void
  158. set_gimp_PLUG_IN_INFO_PTR (GimpPlugInInfo *p)
  159. {
  160.   PLUG_IN_INFO_PTR = p;
  161. }
  162. #else
  163. #ifndef __EMX__
  164. extern GimpPlugInInfo PLUG_IN_INFO;
  165. #else
  166. static GimpPlugInInfo PLUG_IN_INFO;
  167. void set_gimp_PLUG_IN_INFO (const GimpPlugInInfo *p)
  168. {
  169.   PLUG_IN_INFO = *p;
  170. }
  171. #endif
  172. #endif
  173.  
  174.  
  175. int
  176. gimp_main (int   argc,
  177.        char *argv[])
  178. {
  179. #ifdef G_OS_WIN32
  180.   int i, j, k;
  181. #endif
  182.  
  183.   setlocale (LC_ALL, "");
  184.   setlocale (LC_NUMERIC, "C");
  185.  
  186. #ifdef G_OS_WIN32
  187.   g_assert (PLUG_IN_INFO_PTR != NULL);
  188.  
  189.   /* Check for exe file name with spaces in the path having been split up
  190.    * by buggy NT C runtime, or something. I don't know why this happens
  191.    * on NT (including w2k), but not on w95/98.
  192.    */
  193.  
  194.   for (i = 1; i < argc; i++)
  195.     {
  196.       k = strlen (argv[i]);
  197.       if (k > 10)
  198.     if (g_strcasecmp (argv[i] + k - 4, ".exe") == 0)
  199.       {
  200.         /* Found the end of the executable name, most probably.
  201.          * Splice the parts of the name back together.
  202.          */
  203.         GString *s;
  204.  
  205.         s = g_string_new (argv[0]);
  206.         for (j = 1; j <= i; j++)
  207.           {
  208.         s = g_string_append_c (s, ' ');
  209.         s = g_string_append (s, argv[j]);
  210.           }
  211.         argv[0] = s->str;
  212.         /* Move rest of argv down */
  213.         for (j = 1; j < argc - i; j++)
  214.           argv[j] = argv[j + i];
  215.         argv[argc - i] = NULL;
  216.         argc -= i;
  217.         break;
  218.       }
  219.     }
  220. #endif
  221.  
  222.   if ((argc != 6) || (strcmp (argv[1], "-gimp") != 0))
  223.     {
  224.       g_printerr ("%s is a gimp plug-in and must be run by the gimp to be used\n", argv[0]);
  225.       return 1;
  226.     }
  227.  
  228.   progname = argv[0];
  229.  
  230.   g_set_prgname (g_basename (progname));
  231.  
  232.   stack_trace_mode = (GimpStackTraceMode) CLAMP (atoi (argv[5]),
  233.                          GIMP_STACK_TRACE_NEVER,
  234.                          GIMP_STACK_TRACE_ALWAYS);
  235.  
  236. #ifndef G_OS_WIN32
  237.   /* No use catching these on Win32, the user won't get any meaningful
  238.    * stack trace from glib anyhow. It's better to let Windows inform
  239.    * about the program error, and offer debugging if the plug-in
  240.    * has been built with MSVC, and the user has MSVC installed.
  241.    */
  242.   gimp_signal_private (SIGHUP,  gimp_plugin_sigfatal_handler, 0);
  243.   gimp_signal_private (SIGINT,  gimp_plugin_sigfatal_handler, 0);
  244.   gimp_signal_private (SIGQUIT, gimp_plugin_sigfatal_handler, 0);
  245.   gimp_signal_private (SIGBUS,  gimp_plugin_sigfatal_handler, 0);
  246.   gimp_signal_private (SIGSEGV, gimp_plugin_sigfatal_handler, 0);
  247.   gimp_signal_private (SIGTERM, gimp_plugin_sigfatal_handler, 0);
  248.   gimp_signal_private (SIGFPE,  gimp_plugin_sigfatal_handler, 0);
  249.  
  250.   /* Ignore SIGPIPE from crashing Gimp */
  251.   gimp_signal_private (SIGPIPE, SIG_IGN, 0);
  252.  
  253.   /* Restart syscalls interrupted by SIGCHLD */
  254.   gimp_signal_private (SIGCHLD, SIG_DFL, SA_RESTART);
  255. #endif
  256.  
  257.   _readchannel  = g_io_channel_unix_new (atoi (argv[2]));
  258.   _writechannel = g_io_channel_unix_new (atoi (argv[3]));
  259. #ifdef __EMX__
  260.   setmode (g_io_channel_unix_get_fd (_readchannel), O_BINARY);
  261.   setmode (g_io_channel_unix_get_fd (_writechannel), O_BINARY);
  262. #endif
  263.  
  264.   gp_init ();
  265.   wire_set_writer (gimp_write);
  266.   wire_set_flusher (gimp_flush);
  267.  
  268.   g_log_set_handler ("LibGimp",
  269.              G_LOG_LEVEL_MESSAGE,
  270.              gimp_message_func,
  271.              NULL);
  272.   g_log_set_handler (NULL,
  273.              G_LOG_LEVEL_MESSAGE,
  274.              gimp_message_func,
  275.              NULL);
  276.  
  277.   if (strcmp (argv[4], "-query") == 0)
  278.     {
  279.       if (PLUG_IN_INFO.query_proc)
  280.     (* PLUG_IN_INFO.query_proc) ();
  281. #ifdef HACK_FOR_BUG_66859
  282.       /* If we have an init_proc, tell GIMP about it by pretending to
  283.        * install a function with a special marker name.
  284.        */
  285.       if (PLUG_IN_INFO.init_proc)
  286.     gimp_have_init_proc ();
  287. #endif
  288.       gimp_close ();
  289.       return 0;
  290.     }
  291. #ifdef HACK_FOR_BUG_66859
  292.   else if (strcmp (argv[4], "-init") == 0)
  293.     {
  294.       if (PLUG_IN_INFO.init_proc)
  295.     (* PLUG_IN_INFO.init_proc) ();
  296.       gimp_close ();
  297.       return 0;
  298.     }
  299. #endif
  300.  
  301.   temp_proc_ht = g_hash_table_new (g_str_hash, g_str_equal);
  302.  
  303.   g_io_add_watch (_readchannel,
  304.           G_IO_ERR | G_IO_HUP,
  305.           gimp_plugin_io_error_handler,
  306.           NULL);
  307.  
  308.   gimp_loop ();
  309.   return 0;
  310. }
  311.  
  312. #ifdef HACK_FOR_BUG_66859
  313.  
  314. static void
  315. gimp_have_init_proc (void)
  316. {
  317.   gimp_install_procedure (GIMP_HAVE_INIT_PROC_MARKER,
  318.               "",
  319.               "",
  320.               "",
  321.               "",
  322.               "",
  323.               NULL,
  324.               "",
  325.               GIMP_EXTENSION,
  326.               0, 0,
  327.               NULL, NULL);
  328. }
  329.  
  330. #endif /* HACK_FOR_BUG_66859 */
  331.  
  332. static void
  333. gimp_close (void)
  334. {
  335.   if (PLUG_IN_INFO.quit_proc)
  336.     (* PLUG_IN_INFO.quit_proc) ();
  337.  
  338. #if defined(G_OS_WIN32) || defined(G_WITH_CYGWIN)
  339.   CloseHandle (shm_handle);
  340. #else
  341. #ifdef HAVE_SHM_H
  342.   if ((_shm_ID != -1) && _shm_addr)
  343.     shmdt ((char*) _shm_addr);
  344. #endif
  345. #endif
  346.  
  347.   gp_quit_write (_writechannel);
  348. }
  349.  
  350. void
  351. gimp_quit (void)
  352. {
  353.   gimp_close ();
  354.   exit (0);
  355. }
  356.  
  357.  
  358. gint32
  359. gimp_default_display (void)
  360. {
  361.   return _gdisp_ID;
  362. }
  363.  
  364. static void
  365. gimp_message_func (const gchar    *log_domain,
  366.            GLogLevelFlags  log_level,
  367.            const gchar    *message,
  368.            gpointer        data)
  369. {
  370.   gimp_message ((gchar *) message);
  371. }
  372.  
  373. void
  374. gimp_install_procedure (gchar        *name,
  375.             gchar        *blurb,
  376.             gchar        *help,
  377.             gchar        *author,
  378.             gchar        *copyright,
  379.             gchar        *date,
  380.             gchar        *menu_path,
  381.             gchar        *image_types,
  382.             gint          type,
  383.             gint          nparams,
  384.             gint          nreturn_vals,
  385.             GimpParamDef *params,
  386.             GimpParamDef *return_vals)
  387. {
  388.   GPProcInstall proc_install;
  389.  
  390.   proc_install.name         = name;
  391.   proc_install.blurb        = blurb;
  392.   proc_install.help         = help;
  393.   proc_install.author       = author;
  394.   proc_install.copyright    = copyright;
  395.   proc_install.date         = date;
  396.   proc_install.menu_path    = menu_path;
  397.   proc_install.image_types  = image_types;
  398.   proc_install.type         = type;
  399.   proc_install.nparams      = nparams;
  400.   proc_install.nreturn_vals = nreturn_vals;
  401.   proc_install.params       = (GPParamDef *) params;
  402.   proc_install.return_vals  = (GPParamDef *) return_vals;
  403.  
  404.   if (!gp_proc_install_write (_writechannel, &proc_install))
  405.     gimp_quit ();
  406. }
  407.  
  408. void
  409. gimp_install_temp_proc (gchar        *name,
  410.             gchar        *blurb,
  411.             gchar        *help,
  412.             gchar        *author,
  413.             gchar        *copyright,
  414.             gchar        *date,
  415.             gchar        *menu_path,
  416.             gchar        *image_types,
  417.             gint          type,
  418.             gint          nparams,
  419.             gint          nreturn_vals,
  420.             GimpParamDef *params,
  421.             GimpParamDef *return_vals,
  422.             GimpRunProc   run_proc)
  423. {
  424.   gimp_install_procedure (name,
  425.               blurb, help,
  426.               author, copyright, date,
  427.               menu_path,
  428.               image_types,
  429.               type,
  430.               nparams, nreturn_vals,
  431.               params, return_vals);
  432.  
  433.   /*  Insert the temp proc run function into the hash table  */
  434.   g_hash_table_insert (temp_proc_ht, g_strdup (name), (gpointer) run_proc);
  435. }
  436.  
  437. void
  438. gimp_uninstall_temp_proc (gchar *name)
  439. {
  440.   GPProcUninstall proc_uninstall;
  441.   gpointer hash_name;
  442.   gboolean found;
  443.   proc_uninstall.name = name;
  444.  
  445.   if (!gp_proc_uninstall_write (_writechannel, &proc_uninstall))
  446.     gimp_quit ();
  447.   
  448.   found = g_hash_table_lookup_extended (temp_proc_ht, name, &hash_name, NULL);
  449.   if (found)
  450.     {
  451.       g_hash_table_remove (temp_proc_ht, (gpointer) name);
  452.       g_free (hash_name);
  453.     }
  454. }
  455.  
  456. GimpParam *
  457. gimp_run_procedure (gchar *name,
  458.             gint  *nreturn_vals,
  459.             ...)
  460. {
  461.   GPProcRun       proc_run;
  462.   GPProcReturn   *proc_return;
  463.   WireMessage     msg;
  464.   GimpPDBArgType  param_type;
  465.   GimpParam      *return_vals;
  466.   va_list         args;
  467.   guchar         *color;
  468.   gint            i;
  469.  
  470.   proc_run.name = name;
  471.   proc_run.nparams = 0;
  472.   proc_run.params = NULL;
  473.  
  474.   va_start (args, nreturn_vals);
  475.   param_type = va_arg (args, GimpPDBArgType);
  476.  
  477.   while (param_type != GIMP_PDB_END)
  478.     {
  479.       switch (param_type)
  480.     {
  481.     case GIMP_PDB_INT32:
  482.         case GIMP_PDB_DISPLAY:
  483.         case GIMP_PDB_IMAGE:
  484.         case GIMP_PDB_LAYER:
  485.         case GIMP_PDB_CHANNEL:
  486.         case GIMP_PDB_DRAWABLE:
  487.         case GIMP_PDB_SELECTION:
  488.         case GIMP_PDB_BOUNDARY:
  489.         case GIMP_PDB_PATH:
  490.         case GIMP_PDB_STATUS:
  491.       (void) va_arg (args, gint);
  492.       break;
  493.     case GIMP_PDB_INT16:
  494.       (void) va_arg (args, gint);
  495.       break;
  496.     case GIMP_PDB_INT8:
  497.       (void) va_arg (args, gint);
  498.       break;
  499.         case GIMP_PDB_FLOAT:
  500.           (void) va_arg (args, gdouble);
  501.           break;
  502.         case GIMP_PDB_STRING:
  503.           (void) va_arg (args, gchar *);
  504.           break;
  505.         case GIMP_PDB_INT32ARRAY:
  506.           (void) va_arg (args, gint32 *);
  507.           break;
  508.         case GIMP_PDB_INT16ARRAY:
  509.           (void) va_arg (args, gint16 *);
  510.           break;
  511.         case GIMP_PDB_INT8ARRAY:
  512.           (void) va_arg (args, gint8 *);
  513.           break;
  514.         case GIMP_PDB_FLOATARRAY:
  515.           (void) va_arg (args, gdouble *);
  516.           break;
  517.         case GIMP_PDB_STRINGARRAY:
  518.           (void) va_arg (args, gchar **);
  519.           break;
  520.         case GIMP_PDB_COLOR:
  521.           (void) va_arg (args, guchar *);
  522.           break;
  523.         case GIMP_PDB_PARASITE:
  524.           (void) va_arg (args, GimpParasite *);
  525.           break;
  526.         case GIMP_PDB_REGION:
  527.           break;
  528.     case GIMP_PDB_END:
  529.       break;
  530.     }
  531.  
  532.       proc_run.nparams += 1;
  533.       param_type = va_arg (args, GimpPDBArgType);
  534.     }
  535.  
  536.   va_end (args);
  537.  
  538.   proc_run.params = g_new (GPParam, proc_run.nparams);
  539.  
  540.   va_start (args, nreturn_vals);
  541.  
  542.   for (i = 0; i < proc_run.nparams; i++)
  543.     {
  544.       proc_run.params[i].type = va_arg (args, GimpPDBArgType);
  545.  
  546.       switch (proc_run.params[i].type)
  547.     {
  548.     case GIMP_PDB_INT32:
  549.       proc_run.params[i].data.d_int32 = (gint32) va_arg (args, gint);
  550.       break;
  551.     case GIMP_PDB_INT16:
  552.       proc_run.params[i].data.d_int16 = (gint16) va_arg (args, gint);
  553.       break;
  554.     case GIMP_PDB_INT8:
  555.       proc_run.params[i].data.d_int8 = (gint8) va_arg (args, gint);
  556.       break;
  557.         case GIMP_PDB_FLOAT:
  558.           proc_run.params[i].data.d_float = (gdouble) va_arg (args, gdouble);
  559.           break;
  560.         case GIMP_PDB_STRING:
  561.           proc_run.params[i].data.d_string = va_arg (args, gchar *);
  562.           break;
  563.         case GIMP_PDB_INT32ARRAY:
  564.           proc_run.params[i].data.d_int32array = va_arg (args, gint32 *);
  565.           break;
  566.         case GIMP_PDB_INT16ARRAY:
  567.           proc_run.params[i].data.d_int16array = va_arg (args, gint16 *);
  568.           break;
  569.         case GIMP_PDB_INT8ARRAY:
  570.           proc_run.params[i].data.d_int8array = va_arg (args, gint8 *);
  571.           break;
  572.         case GIMP_PDB_FLOATARRAY:
  573.           proc_run.params[i].data.d_floatarray = va_arg (args, gdouble *);
  574.           break;
  575.         case GIMP_PDB_STRINGARRAY:
  576.           proc_run.params[i].data.d_stringarray = va_arg (args, gchar **);
  577.           break;
  578.         case GIMP_PDB_COLOR:
  579.       color = va_arg (args, guchar *);
  580.           proc_run.params[i].data.d_color.red   = color[0];
  581.           proc_run.params[i].data.d_color.green = color[1];
  582.           proc_run.params[i].data.d_color.blue  = color[2];
  583.           break;
  584.         case GIMP_PDB_REGION:
  585.           break;
  586.         case GIMP_PDB_DISPLAY:
  587.       proc_run.params[i].data.d_display = va_arg (args, gint32);
  588.           break;
  589.         case GIMP_PDB_IMAGE:
  590.       proc_run.params[i].data.d_image = va_arg (args, gint32);
  591.           break;
  592.         case GIMP_PDB_LAYER:
  593.       proc_run.params[i].data.d_layer = va_arg (args, gint32);
  594.           break;
  595.         case GIMP_PDB_CHANNEL:
  596.       proc_run.params[i].data.d_channel = va_arg (args, gint32);
  597.           break;
  598.         case GIMP_PDB_DRAWABLE:
  599.       proc_run.params[i].data.d_drawable = va_arg (args, gint32);
  600.           break;
  601.         case GIMP_PDB_SELECTION:
  602.       proc_run.params[i].data.d_selection = va_arg (args, gint32);
  603.           break;
  604.         case GIMP_PDB_BOUNDARY:
  605.       proc_run.params[i].data.d_boundary = va_arg (args, gint32);
  606.           break;
  607.         case GIMP_PDB_PATH:
  608.       proc_run.params[i].data.d_path = va_arg (args, gint32);
  609.           break;
  610.         case GIMP_PDB_PARASITE:
  611.       {
  612.         GimpParasite *parasite = va_arg (args, GimpParasite *);
  613.  
  614.         if (parasite == NULL)
  615.           {
  616.         proc_run.params[i].data.d_parasite.name = NULL;
  617.         proc_run.params[i].data.d_parasite.data = NULL;
  618.           }
  619.         else
  620.           {
  621.         proc_run.params[i].data.d_parasite.name  = parasite->name;
  622.         proc_run.params[i].data.d_parasite.flags = parasite->flags;
  623.         proc_run.params[i].data.d_parasite.size  = parasite->size;
  624.         proc_run.params[i].data.d_parasite.data  = parasite->data;
  625.           }
  626.       }
  627.       break;
  628.         case GIMP_PDB_STATUS:
  629.       proc_run.params[i].data.d_status = va_arg (args, gint32);
  630.           break;
  631.     case GIMP_PDB_END:
  632.       break;
  633.     }
  634.     }
  635.  
  636.   va_end (args);
  637.  
  638.   if (!gp_proc_run_write (_writechannel, &proc_run))
  639.     gimp_quit ();
  640.  
  641.   gimp_read_expect_msg (&msg, GP_PROC_RETURN);
  642.  
  643.   proc_return = msg.data;
  644.   *nreturn_vals = proc_return->nparams;
  645.   return_vals = (GimpParam*) proc_return->params;
  646.  
  647.   switch (return_vals[0].data.d_status)
  648.     {
  649.     case GIMP_PDB_EXECUTION_ERROR:
  650.       /*g_warning ("an execution error occured while trying to run: \"%s\"", name);*/
  651.       break;
  652.     case GIMP_PDB_CALLING_ERROR:
  653.       g_warning ("a calling error occured while trying to run: \"%s\"", name);
  654.       break;
  655.     default:
  656.       break;
  657.     }
  658.  
  659.   g_free (proc_run.params);
  660.   g_free (proc_return->name);
  661.   g_free (proc_return);
  662.  
  663.   return return_vals;
  664. }
  665.  
  666. void
  667. gimp_read_expect_msg (WireMessage *msg, 
  668.               gint         type)
  669. {
  670.   while (TRUE)
  671.     {
  672.       if (!wire_read_msg (_readchannel, msg))
  673.     gimp_quit ();
  674.       
  675.       if (msg->type != type)
  676.     {
  677.       if (msg->type == GP_TEMP_PROC_RUN || msg->type == GP_QUIT)
  678.         {
  679.           gimp_process_message (msg);
  680.           continue;
  681.         }
  682.       else
  683.         g_error ("unexpected message: %d\n", msg->type);
  684.     }
  685.       else
  686.     break;
  687.     }
  688. }
  689.  
  690.  
  691. GimpParam *
  692. gimp_run_procedure2 (gchar     *name,
  693.              gint      *nreturn_vals,
  694.              gint       nparams,
  695.              GimpParam *params)
  696. {
  697.   GPProcRun     proc_run;
  698.   GPProcReturn *proc_return;
  699.   WireMessage   msg;
  700.   GimpParam    *return_vals;
  701.  
  702.   proc_run.name    = name;
  703.   proc_run.nparams = nparams;
  704.   proc_run.params  = (GPParam *) params;
  705.  
  706.   if (!gp_proc_run_write (_writechannel, &proc_run))
  707.     gimp_quit ();
  708.  
  709.   gimp_read_expect_msg(&msg,GP_PROC_RETURN);
  710.   
  711.   proc_return = msg.data;
  712.   *nreturn_vals = proc_return->nparams;
  713.   return_vals = (GimpParam *) proc_return->params;
  714.  
  715.   switch (return_vals[0].data.d_status)
  716.     {
  717.     case GIMP_PDB_EXECUTION_ERROR:
  718.       /*g_warning ("an execution error occured while trying to run: \"%s\"", name);*/
  719.       break;
  720.     case GIMP_PDB_CALLING_ERROR:
  721.       g_warning ("a calling error occured while trying to run: \"%s\"", name);
  722.       break;
  723.     default:
  724.       break;
  725.     }
  726.  
  727.   g_free (proc_return->name);
  728.   g_free (proc_return);
  729.  
  730.   return return_vals;
  731. }
  732.  
  733. void
  734. gimp_destroy_params (GimpParam *params,
  735.              gint       nparams)
  736. {
  737.   extern void _gp_params_destroy (GPParam *params, gint nparams);
  738.  
  739.   _gp_params_destroy ((GPParam*) params, nparams);
  740. }
  741.  
  742. void
  743. gimp_destroy_paramdefs (GimpParamDef *paramdefs,
  744.             gint          nparams)
  745. {
  746.   while (nparams--)
  747.     {
  748.       g_free (paramdefs[nparams].name);
  749.       g_free (paramdefs[nparams].description);
  750.     }
  751.  
  752.   g_free (paramdefs);
  753. }
  754.  
  755. gdouble
  756. gimp_gamma (void)
  757. {
  758.   return _gamma_val;
  759. }
  760.  
  761. gboolean
  762. gimp_install_cmap (void)
  763. {
  764.   return _install_cmap;
  765. }
  766.  
  767. gboolean
  768. gimp_use_xshm (void)
  769. {
  770.   return _use_xshm;
  771. }
  772.  
  773. guchar *
  774. gimp_color_cube (void)
  775. {
  776.   return _color_cube;
  777. }
  778.  
  779. gint
  780. gimp_min_colors (void)
  781. {
  782.   return _min_colors;
  783. }
  784.  
  785. static void
  786. gimp_process_message (WireMessage *msg)
  787. {
  788.   switch (msg->type)
  789.     {
  790.     case GP_QUIT:
  791.       gimp_quit ();
  792.       break;
  793.     case GP_CONFIG:
  794.       gimp_config (msg->data);
  795.       break;
  796.     case GP_TILE_REQ:
  797.     case GP_TILE_ACK:
  798.     case GP_TILE_DATA:
  799.       g_warning ("unexpected tile message received (should not happen)\n");
  800.       break;
  801.     case GP_PROC_RUN:
  802.       g_warning ("unexpected proc run message received (should not happen)\n");
  803.       break;
  804.     case GP_PROC_RETURN:
  805.       g_warning ("unexpected proc return message received (should not happen)\n");
  806.       break;
  807.     case GP_TEMP_PROC_RUN:
  808.       gimp_temp_proc_run (msg->data);
  809.       break;
  810.     case GP_TEMP_PROC_RETURN:
  811.       g_warning ("unexpected temp proc return message received (should not happen)\n");
  812.       break;
  813.     case GP_PROC_INSTALL:
  814.       g_warning ("unexpected proc install message received (should not happen)\n");
  815.       break;
  816.     }
  817. }
  818.  
  819. static void 
  820. gimp_single_message (void)
  821. {
  822.   WireMessage msg;
  823.  
  824.   /* Run a temp function */
  825.   if (!wire_read_msg (_readchannel, &msg))
  826.     gimp_quit ();
  827.  
  828.   gimp_process_message (&msg);
  829.   
  830.   wire_destroy (&msg);
  831. }
  832.  
  833. void
  834. gimp_extension_process (guint timeout)
  835. {
  836. #ifndef G_OS_WIN32
  837.   fd_set readfds;
  838.   gint   select_val;
  839.   struct timeval  tv;
  840.   struct timeval *tvp;
  841.  
  842.   if (timeout)
  843.     {
  844.       tv.tv_sec = timeout / 1000;
  845.       tv.tv_usec = (timeout % 1000) * 1000;
  846.       tvp = &tv;
  847.     }
  848.   else
  849.     tvp = NULL;
  850.  
  851.   FD_ZERO (&readfds);
  852.   FD_SET (g_io_channel_unix_get_fd (_readchannel), &readfds);
  853.  
  854.   if ((select_val = select (FD_SETSIZE, &readfds, NULL, NULL, tvp)) > 0)
  855.     {
  856.       gimp_single_message ();
  857.     }
  858.   else if (select_val == -1)
  859.     {
  860.       perror ("gimp_process");
  861.       gimp_quit ();
  862.     }
  863. #else
  864.   /* Zero means infinite wait for us, but g_poll and
  865.    * g_io_channel_win32_poll use -1 to indicate
  866.    * infinite wait.
  867.    */
  868.   GPollFD pollfd;
  869.  
  870.   if (timeout == 0)
  871.     timeout = -1;
  872.  
  873.   g_io_channel_win32_make_pollfd (_readchannel, G_IO_IN, &pollfd);
  874.  
  875.   if (g_io_channel_win32_poll (&pollfd, 1, timeout) == 1)
  876.     gimp_single_message ();
  877. #endif
  878. }
  879.  
  880. void
  881. gimp_extension_ack (void)
  882. {
  883.   /*  Send an extension initialization acknowledgement  */
  884.   if (! gp_extension_ack_write (_writechannel))
  885.     gimp_quit ();
  886. }
  887.  
  888. void
  889. gimp_run_temp (void)
  890. {
  891.   gimp_single_message ();
  892. }
  893.  
  894. gchar *
  895. gimp_get_progname (void)
  896. {
  897.   return progname;
  898. }
  899.  
  900. #ifndef G_OS_WIN32
  901. static void
  902. gimp_plugin_sigfatal_handler (gint sig_num)
  903. {
  904.   switch (sig_num)
  905.     {
  906.     case SIGHUP:
  907.     case SIGINT:
  908.     case SIGQUIT:
  909.     case SIGABRT:
  910.     case SIGTERM:
  911.       g_printerr ("%s terminated: %s\n", progname, g_strsignal (sig_num));
  912.       break;
  913.  
  914.     case SIGBUS:
  915.     case SIGSEGV:
  916.     case SIGFPE:
  917.     case SIGPIPE:
  918.     default:
  919.       g_printerr ("%s: fatal error: %s\n", progname, g_strsignal (sig_num));
  920.       switch (stack_trace_mode)
  921.     {
  922.     case GIMP_STACK_TRACE_NEVER:
  923.       break;
  924.  
  925.     case GIMP_STACK_TRACE_QUERY:
  926.       {
  927.         sigset_t sigset;
  928.  
  929.         sigemptyset (&sigset);
  930.         sigprocmask (SIG_SETMASK, &sigset, NULL);
  931.         g_on_error_query (progname);
  932.       }
  933.       break;
  934.  
  935.     case GIMP_STACK_TRACE_ALWAYS:
  936.       {
  937.         sigset_t sigset;
  938.  
  939.         sigemptyset (&sigset);
  940.         sigprocmask (SIG_SETMASK, &sigset, NULL);
  941.         g_on_error_stack_trace (progname);
  942.       }
  943.       break;
  944.     }
  945.       break;
  946.     }
  947.  
  948.   gimp_quit ();
  949. }
  950. #endif
  951.  
  952. static gboolean
  953. gimp_plugin_io_error_handler (GIOChannel   *channel,
  954.                   GIOCondition  cond,
  955.                   gpointer      data)
  956. {
  957.   g_printerr ("%s: fatal error: GIMP crashed\n", progname);
  958.   gimp_quit ();
  959.  
  960.   /* never reached */
  961.   return TRUE;
  962. }
  963.  
  964. static gboolean
  965. gimp_write (GIOChannel *channel, 
  966.         guint8     *buf, 
  967.         gulong      count)
  968. {
  969.   gulong bytes;
  970.  
  971.   while (count > 0)
  972.     {
  973.       if ((write_buffer_index + count) >= WRITE_BUFFER_SIZE)
  974.     {
  975.       bytes = WRITE_BUFFER_SIZE - write_buffer_index;
  976.       memcpy (&write_buffer[write_buffer_index], buf, bytes);
  977.       write_buffer_index += bytes;
  978.       if (!wire_flush (channel))
  979.         return FALSE;
  980.     }
  981.       else
  982.     {
  983.       bytes = count;
  984.       memcpy (&write_buffer[write_buffer_index], buf, bytes);
  985.       write_buffer_index += bytes;
  986.     }
  987.  
  988.       buf += bytes;
  989.       count -= bytes;
  990.     }
  991.  
  992.   return TRUE;
  993. }
  994.  
  995. static gboolean
  996. gimp_flush (GIOChannel *channel)
  997. {
  998.   GIOError error;
  999.   guint count;
  1000.   guint bytes;
  1001.  
  1002.   if (write_buffer_index > 0)
  1003.     {
  1004.       count = 0;
  1005.       while (count != write_buffer_index)
  1006.         {
  1007.       do
  1008.         {
  1009.           bytes = 0;
  1010.           error = g_io_channel_write (channel, &write_buffer[count],
  1011.                       (write_buffer_index - count),
  1012.                       &bytes);
  1013.         }
  1014.       while (error == G_IO_ERROR_AGAIN);
  1015.  
  1016.       if (error != G_IO_ERROR_NONE)
  1017.         return FALSE;
  1018.  
  1019.           count += bytes;
  1020.         }
  1021.  
  1022.       write_buffer_index = 0;
  1023.     }
  1024.  
  1025.   return TRUE;
  1026. }
  1027.  
  1028. static void
  1029. gimp_loop (void)
  1030. {
  1031.   WireMessage msg;
  1032.  
  1033.   while (TRUE)
  1034.     {
  1035.       if (!wire_read_msg (_readchannel, &msg))
  1036.         {
  1037.       gimp_close ();
  1038.           return;
  1039.         }
  1040.  
  1041.       switch (msg.type)
  1042.     {
  1043.     case GP_QUIT:
  1044.       gimp_close ();
  1045.       return;
  1046.     case GP_CONFIG:
  1047.       gimp_config (msg.data);
  1048.       break;
  1049.     case GP_TILE_REQ:
  1050.     case GP_TILE_ACK:
  1051.     case GP_TILE_DATA:
  1052.       g_warning ("unexpected tile message received (should not happen)\n");
  1053.       break;
  1054.     case GP_PROC_RUN:
  1055.       gimp_proc_run (msg.data);
  1056.       gimp_close ();
  1057.           return;
  1058.     case GP_PROC_RETURN:
  1059.       g_warning ("unexpected proc return message received (should not happen)\n");
  1060.       break;
  1061.     case GP_TEMP_PROC_RUN:
  1062.       g_warning ("unexpected temp proc run message received (should not happen\n");
  1063.       break;
  1064.     case GP_TEMP_PROC_RETURN:
  1065.       g_warning ("unexpected temp proc return message received (should not happen\n");
  1066.       break;
  1067.     case GP_PROC_INSTALL:
  1068.       g_warning ("unexpected proc install message received (should not happen)\n");
  1069.       break;
  1070.     }
  1071.  
  1072.       wire_destroy (&msg);
  1073.     }
  1074. }
  1075.  
  1076. static void
  1077. gimp_config (GPConfig *config)
  1078. {
  1079.   extern gint _gimp_tile_width;
  1080.   extern gint _gimp_tile_height;
  1081.  
  1082.   if (config->version < GP_VERSION)
  1083.     {
  1084.       g_message ("Could not execute Plug-In \"%s\"\n(%s)\n\n"
  1085.          "The GIMP is using an older version of the "
  1086.          "Plug-In protocol than this Plug-In.",
  1087.          g_basename (progname), progname);
  1088.       gimp_quit ();
  1089.     }
  1090.   else if (config->version > GP_VERSION)
  1091.     {
  1092.       g_message ("Could not execute Plug-In \"%s\"\n(%s)\n\n"
  1093.          "The GIMP is using an older version of the "
  1094.          "Plug-In protocol than this Plug-In.",
  1095.          g_basename (progname), progname);
  1096.       gimp_quit ();
  1097.     }
  1098.  
  1099.   _gimp_tile_width  = config->tile_width;
  1100.   _gimp_tile_height = config->tile_height;
  1101.   _shm_ID           = config->shm_ID;
  1102.   _gamma_val        = config->gamma;
  1103.   _install_cmap     = config->install_cmap;
  1104.   _color_cube[0]    = 6;  /*  These are the former default values  */
  1105.   _color_cube[1]    = 6;  /*  (for backward compatibility only)    */
  1106.   _color_cube[2]    = 4;
  1107.   _color_cube[3]    = 24;
  1108.   _use_xshm         = config->use_xshm;
  1109.   _min_colors       = config->min_colors;
  1110.   _gdisp_ID         = config->gdisp_ID;
  1111.  
  1112.   if (_shm_ID != -1)
  1113.     {
  1114. #if defined(G_OS_WIN32) || defined(G_WITH_CYGWIN)
  1115.       /*
  1116.        * Use Win32 shared memory mechanisms for
  1117.        * transfering tile data
  1118.        */
  1119.       gchar fileMapName[128];
  1120.       gint  tileByteSize = _gimp_tile_width * _gimp_tile_height * 4;
  1121.  
  1122.       /* From the id, derive the file map name */
  1123.       g_snprintf (fileMapName, sizeof (fileMapName), "GIMP%d.SHM", _shm_ID);
  1124.  
  1125.       /* Open the file mapping */
  1126.       shm_handle = OpenFileMapping (FILE_MAP_ALL_ACCESS,
  1127.                     0, fileMapName);
  1128.       if (shm_handle)
  1129.     {
  1130.       /* Map the shared memory into our address space for use */
  1131.       _shm_addr = (guchar *) MapViewOfFile (shm_handle,
  1132.                         FILE_MAP_ALL_ACCESS,
  1133.                         0, 0, tileByteSize);
  1134.  
  1135.       /* Verify that we mapped our view */
  1136.       if (!_shm_addr)
  1137.         {
  1138.           g_warning ("MapViewOfFile error: %s... disabling shared memory transport",
  1139.              g_win32_error_message (GetLastError()));
  1140.         }
  1141.     }
  1142.       else
  1143.     {
  1144.       g_warning ("OpenFileMapping error: %s... disabling shared memory transport",
  1145.              g_win32_error_message (GetLastError()));
  1146.     }
  1147. #else
  1148. #ifdef HAVE_SHM_H
  1149.       _shm_addr = (guchar*) shmat (_shm_ID, 0, 0);
  1150.  
  1151.       if (_shm_addr == (guchar*) -1)
  1152.     g_error ("could not attach to gimp shared memory segment\n");
  1153. #endif
  1154. #endif
  1155.     }
  1156. }
  1157.  
  1158. static void
  1159. gimp_proc_run (GPProcRun *proc_run)
  1160. {
  1161.   GPProcReturn proc_return;
  1162.   GimpParam *return_vals;
  1163.   gint nreturn_vals;
  1164.  
  1165.   if (PLUG_IN_INFO.run_proc)
  1166.     {
  1167.       (* PLUG_IN_INFO.run_proc) (proc_run->name,
  1168.                  proc_run->nparams,
  1169.                  (GimpParam*) proc_run->params,
  1170.                  &nreturn_vals,
  1171.                  &return_vals);
  1172.  
  1173.       proc_return.name = proc_run->name;
  1174.       proc_return.nparams = nreturn_vals;
  1175.       proc_return.params = (GPParam*) return_vals;
  1176.  
  1177.       if (!gp_proc_return_write (_writechannel, &proc_return))
  1178.     gimp_quit ();
  1179.     }
  1180. }
  1181.  
  1182. static void
  1183. gimp_temp_proc_run (GPProcRun *proc_run)
  1184. {
  1185.   GimpParam   *return_vals;
  1186.   gint         nreturn_vals;
  1187.   GimpRunProc  run_proc;
  1188.  
  1189.   run_proc = (GimpRunProc) g_hash_table_lookup (temp_proc_ht, 
  1190.                         (gpointer) proc_run->name);
  1191.  
  1192.   if (run_proc)
  1193.     {
  1194.       (* run_proc) (proc_run->name,
  1195.             proc_run->nparams,
  1196.             (GimpParam*) proc_run->params,
  1197.             &nreturn_vals,
  1198.             &return_vals);
  1199.  
  1200.       /* No longer a return message */
  1201. /*       proc_return.name = proc_run->name; */
  1202. /*       proc_return.nparams = nreturn_vals; */
  1203. /*       proc_return.params = (GPParam*) return_vals; */
  1204.  
  1205. /*       if (!gp_temp_proc_return_write (_writechannel, &proc_return)) */
  1206. /*     gimp_quit (); */
  1207.     }
  1208. }
  1209.